Header not getting set properly in android-Retrofit - java

I'm building an app for sending access-token to the server using Retrofit in android. I don't get any error what I think should set the header correctly is not working so.
The header that I want:
"Authorization: Bearer facebook <user_access_token>"
is the token that I get. Not written here for security purposes.
I am using android Retrofit for the purpose with the files as follows:
MainActivity.java
package com.example.apurva.myapplication;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.os.StrictMode;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
UserService userService;
String token = "Bearer facebook <user_access_token>";
userService = ServiceGenerator.createService(UserService.class, UserService.BASE_URL, token);
User user = userService.me();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
UserService.java
package com.example.apurva.myapplication;
import com.squareup.okhttp.OkHttpClient;
import retrofit.Callback;
import retrofit.RequestInterceptor;
import retrofit.RestAdapter;
import retrofit.client.OkClient;
import retrofit.http.POST;
/**
* Created by apurva on 4/8/15.
*/
public interface UserService {
public static final String BASE_URL = "http://10.0.2.2:8000/auth";
#POST("/convert-token")
User me();
}
ServiceGenerator.java
package com.example.apurva.myapplication;
import com.squareup.okhttp.OkHttpClient;
import retrofit.RequestInterceptor;
import retrofit.RestAdapter;
import retrofit.client.OkClient;
/**
* Created by apurva on 4/8/15.
*/
public class ServiceGenerator {
private ServiceGenerator() {
}
public static <S> S createService(Class<S> serviceClass, String baseUrl, final String token) {
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(baseUrl)
.setClient(new OkClient(new OkHttpClient()));
if (token != null) {
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
request.addHeader("Accept", "application/json");
request.addHeader("Authorization", token);
}
});
}
RestAdapter adapter = builder.build();
return adapter.create(serviceClass);
}
}
I would like to mention that there are no errors. I have already set network activity in the main thread by using StrictMode so that is not an issue as well just it does not give the desired result as the user in not getting added in the backend.
I would also like to tel you that I've already checked my back end with cURL and it works fine so there is no issue there as well.
I get runtime error:
Process: com.example.apurva.myapplication, PID: 7140
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.apurva.myapplication/com.example.apurva.myapplication.MainActivity}: retrofit.RetrofitError: 405 METHOD NOT ALLOWED
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: retrofit.RetrofitError: 405 METHOD NOT ALLOWED
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:388)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at $Proxy0.me(Native Method)
at com.example.apurva.myapplication.MainActivity.onCreate(MainActivity.java:24)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)

Your code is ok. You should add logging to your Retrofit.
// Simple add .setLogLevel(RestAdapter.LogLevel.FULL)
RestAdapter.Builder builder = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(baseUrl)
.setClient(new OkClient(new OkHttpClient()));
I'm sure after this you will see in console:
---> HTTP POST http://10.0.2.2:8000/auth/convert-token
Accept: application/json
Authorization: Bearer facebook <user_access_token>
---> END HTTP (no body)
That means your header is set correctly.
"HTTP 405 METHOD NOT ALLOWED" may say that POST method is not expected for this resource. And maybe GET request will help you:
#GET("/convert-token")
User me();

Hi Please Refer githublink and it will give some Idea,let me explain basic functionality here,
Create a Interface:
public interface MyApiEndPointInterface {
/* #GET("contacts/")
Call<UserPojo> getHiveDetails();*/
#FormUrlEncoded
#POST("authorize/")
Call<SmsLogin> getUser(#Field("username") String username,
#Field("password") String password);
//GetProfile Details
#GET("getprofile")
Call<SmsProfilePojo> getProfileDetails(#Header("Authorizations") String myTokenValue);
}
UserProfilePreview.java is An Activity,Please LookUp this Class in repo,It give basic Idea.
private void getApiCAll() {
OkHttpClient okClient = new OkHttpClient.Builder() .addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder()
.addHeader("Accept","Application/JSON").build();
return chain.proceed(request);
}
}).build();
retrofitRef = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
final MyApiEndPointInterface service = retrofitRef.create(MyApiEndPointInterface.class);
String myTokenStr = "Bearer "+mToken;
Call<SmsProfilePojo> call = service.getProfileDetails(myTokenStr);
call.enqueue(new Callback<SmsProfilePojo>() {
#Override
public void onResponse(Call<SmsProfilePojo> call, retrofit2.Response<SmsProfilePojo> response) {
Log.d(TAG,"OnResponse: "+ response.code());
if(response.isSuccessful()){
SmsProfilePojo result = response.body();
mToken = result.getToken();
txtVw_Token.setText(mToken);
}else{
Toast.makeText(getApplicationContext(),"Fail in Response",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<SmsProfilePojo> call, Throwable t) {
Toast.makeText(getApplicationContext(),"Failed",Toast.LENGTH_SHORT).show();
}
});
}

Related

Unable to instantiate activity ComponentInfo - AndroidStudio

I am a complete beginner to android/Java development and I massively appreciate any pointers anyone is able to give me on the issue I'm having. Here is the MainActivity.java.
package com.example.harris.enterappman;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
EditText enterName;
TextView usersName;
String str = enterName.getText().toString();
public void getName(View view){
enterName = (EditText) findViewById(R.id.enterName);
usersName = (TextView) findViewById(R.id.helloNameView);
usersName.setText(str);
}
public void printUsersName(){
}
}
Everytime I try and run the program, it fails with the error:
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.harris.enterappman/com.example.harris.enterappman.Main Activity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2121)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5021)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.harris.enterappman.MainActivity.<init>(MainActivity.java:48)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newActivity(Instrumentation.java:1064)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2112)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
            at android.app.ActivityThread.access$800(ActivityThread.java:135)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5021)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:827)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:643)
            at dalvik.system.NativeStart.main(Native Method)
From others posts online I have come to the conclusion that the problem is related to abstract methods? I was unable to work out how my code was wrong.
Cheers,
Harris
String str = enterName.getText().toString();
enterName is null at this point, as you are not setting it ever. You are welcome to declare String str; as a field, but you cannot initialize it until after you set a value on enterName.
You have code to initialize enterName in a somewhat strange getName() method, but you do not appear to be calling that ever.
you have not initialised entername properly
either use:
....
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
enterName = (EditText) findViewById(R.id.enterName);
usersName = (TextView) findViewById(R.id.helloNameView);
usersName.setText(str);
}
...
or use it like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getName();
}
public void getName(){
enterName = (EditText) findViewById(R.id.enterName);
usersName = (TextView) findViewById(R.id.helloNameView);
usersName.setText(str);
}
You call enterName.getText() when enterName is null, which leads to NullPointerException.
Few things I suggest:
If you want to own references to the layout components, call these in the onCreate method:
enterName = (EditText) findViewById(R.id.enterName);
usersName = (TextView) findViewById(R.id.helloNameView);
Don't call methods in the class itself (except some constructors), call them in a method (I refer to the str variable).
how possible you are setting your str using enterName, as enterName is not initialized and hence it is null causing Null pointer exception
you must have to initilize enterName before using it, as you are doing initialization in your getName() method, and then use it to get its text
your code must be like this and you have to call this method from onCreate()
public void getName(View view){
enterName = (EditText) findViewById(R.id.enterName);
usersName = (TextView) findViewById(R.id.helloNameView);
usersName.setText(enterName.getText().toString());
}

Trying to save JSON string into a class to parce between activities (NPE)

I am trying to save my JSON string into a class so that I can pass around that object between activities and not lose any data when pressing the back button. However as I try to set the string into the object I receive a NullPointerException. Here is the code for my java file where the exception is occurring, the class java file, and the error. I am using GSON to serialize and deserialize. Any suggestions as to why this is happening?
NewLocation.java
package com.customledsupply.ledaudit;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Parcelable;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import com.google.gson.Gson;
public class NewLocation extends ActionBarActivity {
public EditText editCoName;
public EditText editCoAddress;
public EditText editCoContact;
public EditText editSqFt;
public EditText editTaxed;
public EditText editConcerns;
public JSON_String json;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_location);
findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SaveInfo();
Intent i = new Intent(NewLocation.this, RoomList.class);
i.putExtra("json", (Parcelable) json);
startActivity(i);
}
});
editCoName = (EditText) findViewById(R.id.CoName);
editCoAddress = (EditText) findViewById(R.id.CoAddress);
editCoContact = (EditText) findViewById(R.id.CoContact);
editSqFt = (EditText) findViewById(R.id.SqFt);
editTaxed = (EditText) findViewById(R.id.Taxed);
editConcerns = (EditText) findViewById(R.id.Concerns);
SaveInfo();
}
#Override
protected void onResume() {
super.onResume();
LoadInfo();
}
#Override
protected void onDestroy() {
super.onDestroy();
SaveInfo();
}
public void SaveInfo() {
Gson gson = new Gson();
CompanyInfo companyInfo = new CompanyInfo();
companyInfo.setName(editCoName.getText().toString());
companyInfo.setAddress(editCoAddress.getText().toString());
companyInfo.setContact(editCoContact.getText().toString());
companyInfo.setTaxed(editTaxed.getText().toString());
companyInfo.setSqFt(editSqFt.getText().toString());
companyInfo.setConcerns(editConcerns.getText().toString());
json.setJson(gson.toJson(companyInfo));
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("json", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("json", json.getJson());
editor.apply();
}
public void LoadInfo() {
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("json", MODE_PRIVATE);
json.setJson(sharedPreferences.getString("json", null));
Gson gson = new Gson();
CompanyInfo companyInfo = gson.fromJson(json.getJson(), CompanyInfo.class);
if (companyInfo != null) {
editCoName.setText(companyInfo.getName());
editCoAddress.setText(companyInfo.getAddress());
editCoContact.setText(companyInfo.getContact());
editTaxed.setText(companyInfo.getTaxed());
editSqFt.setText(companyInfo.getSqFt());
editConcerns.setText(companyInfo.getConcerns());
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_new_location, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch(item.getItemId())
{
case R.id.home:
startActivity(new Intent(getApplicationContext(), MainPage.class));
break;
}
return super.onOptionsItemSelected(item);
}
}
JSON_String.java
package com.customledsupply.ledaudit;
public class JSON_String {
private String json;
public void setJson(String json) {
this.json = json;
}
public String getJson() {
return json;
}
}
NPE error
08-03 08:46:52.081 24423-24423/com.customledsupply.ledaudit E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.customledsupply.ledaudit, PID: 24423
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.customledsupply.ledaudit/com.customledsupply.ledaudit.NewLocation}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2198)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2248)
at android.app.ActivityThread.access$800(ActivityThread.java:138)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5061)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.customledsupply.ledaudit.NewLocation.SaveInfo(NewLocation.java:78)
at com.customledsupply.ledaudit.NewLocation.onCreate(NewLocation.java:52)
at android.app.Activity.performCreate(Activity.java:5237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2248)
            at android.app.ActivityThread.access$800(ActivityThread.java:138)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1199)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5061)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:780)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:596)
            at dalvik.system.NativeStart.main(Native Method)
You're trying to cast your json to Parcelable:
i.putExtra("json", (Parcelable) json);
Just pass as a string and in your RoomList.class get from bundle. Cast it to your class with gson and use it.
Your json is null, hence the error. To onCreate add
json = new JSON_String();
If you want to keep passing the object between activites, and not lose it when back button is pressed, you should use startActivityForResults(). This will require you to implement a couple of methods that take care of passing objects between activities. This is a good tutorial.
The problem is You didn't initialize your JSON_String class. You need to initialize the JSON_String like
public JSON_String json = new JSON_String();
Have you tried to initlize the json string?

Android DexClassLoader error, 'optimized data directory .. not owned by current user'

I am trying to produce a simple android application that can load a DEX file from the SD card at run-time.
The application has two activites. The first activity is a simple screen that has a button. When the button is pressed, the second activity is launched which causes the loadDex() method to be invoked. The loadDex() method attempts to locate a jar file on the SD card and load it into the current application.
Here is my code for the first activity:
package poc.example.del.customclass;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void launchLoadClass(View view) {
Intent intent = new Intent(MainActivity.this, LoadClass.class);
startActivity(intent);
}
}
Here is the code for my second activity (the one that loads the DEX file):
package poc.example.del.customclass;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import dalvik.system.DexClassLoader;
public class LoadClass extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_load_class);
loadDex();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_load_class, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void loadDex() {
String dexFile = "/sdcard/output.jar";
File jarFile = new File(dexFile);
if (jarFile.exists()) {
// Toast.makeText(getApplicationContext(), "It Worked!", Toast.LENGTH_LONG).show();
DexClassLoader cl = new DexClassLoader (jarFile.toString (), "/data/test", null, ClassLoader.getSystemClassLoader());
}
}
}
The issue arise when the DexClassLoader constructor is called. The following error can be found in the log:
03-25 10:15:48.441 1934-1934/poc.example.del.customclass E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{poc.example.del.customclass/poc.example.del.customclass.LoadClass}: java.lang.IllegalArgumentException: Optimized data directory /data/test is not owned by the current user. Shared storage cannot protect your application from code injection attacks.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Optimized data directory /data/test is not owned by the current user. Shared storage cannot protect your application from code injection attacks.
at dalvik.system.DexFile.<init>(DexFile.java:100)
at dalvik.system.DexFile.loadDex(DexFile.java:149)
at dalvik.system.DexPathList.loadDexFile(DexPathList.java:261)
at dalvik.system.DexPathList.makeDexElements(DexPathList.java:229)
at dalvik.system.DexPathList.<init>(DexPathList.java:96)
at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:56)
at dalvik.system.DexClassLoader.<init>(DexClassLoader.java:57)
at poc.example.del.customclass.LoadClass.loadDex(LoadClass.java:54)
at poc.example.del.customclass.LoadClass.onCreate(LoadClass.java:23)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5039)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
            at dalvik.system.NativeStart.main(Native Method)
Here is the line in the log that I believe represents the issue:
java.lang.IllegalArgumentException: Optimized data directory /data/test is not owned by the current user. Shared storage cannot protect your application from code injection attacks.
Any help would be appreciate as I have found very little information on the web regarding the issue. I am developing the application for Android 4.2, Api 17.
Thanks in advance.
I found an answer after a few days of following various tutorials. I thought id post the solution here in case anyone else has a similar problem.
For security reasons, Android does not allow the application to load files to any random folder. Instead it should be loaded to the applications environment. Here is the modified code that has allowed me to continue with the project. The code shown is for the 'loadDex()' method:
public void loadDex() {
// Toast the show the method has been invoked correctly
// Toast.makeText(getApplicationContext(), "loadDex() Method invoked", Toast.LENGTH_LONG).show();
// name of the DEX file
String dexFile = "/output.jar";
// Get the path to the SD card
File f = new File(Environment.getExternalStorageDirectory().toString() + dexFile);
// optimized directory, the applciation and package directory
final File optimizedDexOutputPath = getDir("outdex", 0);
// DexClassLoader to get the file and write it to the optimised directory
DexClassLoader classLoader = new DexClassLoader(f.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(),null, getClassLoader());
// The classpath is created for the new class
String completeClassName = "poc.example.del.mylibrary.name";
String methodToInvoke = "display";
try {
Class<?> myClass = classLoader.loadClass(completeClassName);
Object obj = (Object)myClass.newInstance();
Method m = myClass.getMethod(methodToInvoke);
String s = ""+m.invoke(obj);
makeToast(s);
}
catch (Exception e) {
e.printStackTrace();
makeToast("Something went wrong!");
}
}
The specific line(s) of code that resolved the problem is:
// DexClassLoader to get the file and write it to the optimized directory
DexClassLoader classLoader = new DexClassLoader(f.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(),null, getClassLoader());
As you can see, the optimizedDexOutputPath,getAbsolutePath() method returns the directory that can be used to write files to by the application.
Hope this helps anyone else with a similar issue!

HTTP Request Android - Attempt to invoke virtual method

So I have a problem. I have been trying to get an http request to work for quite a while now, and I have made a new thread so that the request never runs on the main thread. I have successfully made it so that the HTTP Request occurs and in the request thread I have made it so it logs the data that it has grabbed from the http request. Now if I ever want to use this jsonObject outside the method it gives me errors. Help?
LogCat:
02-23 22:48:08.612 4239-4239/com.tamrefrank.www.listviewandroidstudio E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.tamrefrank.www.listviewandroidstudio, PID: 4239
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tamrefrank.www.listviewandroidstudio/com.tamrefrank.www.listviewandroidstudio.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.json.JSONArray.toString()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.json.JSONArray.toString()' on a null object reference
at com.tamrefrank.www.listviewandroidstudio.MainActivity.onCreate(MainActivity.java:38)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
02-23 22:48:09.332 4239-4254/com.tamrefrank.www.listviewandroidstudio I/log_tag﹕ [{"Name":"Cabinet","Location":"In Storage","Latitude":"40.83990100","Longitude":"14.25185000","pk":19587,"image_id":"2006AJ6728"},{"Name":"Panel","Location":"Medieval and Renaissance, room 8, case WS EXP","Latitude":"48.87287900","Longitude":"4.63710000","pk":11371,"image_id":"2006AP3163"},{"Name":"Wallpaper","Location":"British Galleries, room 122f, case 1","Latitude":"53.47962200","Longitude":"-2.24881000","pk":19492,"image_id":"2006AU6265"},{"Name":"Portrait miniature","Location":"British Galleries, room 58c, case 2","Latitude":"52.88328900","Longitude":"-1.97685000","pk":9491,"image_id":"2006AH0271"},{"Name":"Caricature","Location":"In Storage","Latitude":"53.02513900","Longitude":"-2.18676000","pk":29979,"image_id":"2006AE9142"},{"Name":"Card game","Location":"In Storage","Latitude":"52.88328900","Longitude":"-1.97685000","pk":26483,"image_id":"2006AU5916"},{"Name":"Tile","Location":"Islamic Middle East, room 42, case WW9","Latitude":"39.76586200","Longitude":"64.42234000","pk":30220,"image_id":"2006AY5617"},{"Name":"Sculpture","Location":"Sculpture, room 22, case 2","Latitude":"52.88328900","Longitude":"-1.97685000","pk":36026,"image_id":"2006AM7780"},{"Name":"Oil painting","Location":"Prints & Drawings Study Room, room 315, case 24, shelf R","Latitude":"52.88328900","Longitude":"-1.97685000","pk":6905,"image_id":"2006AU6480"},{"Name":"Snuff bottle","Location":"In Storage","Latitude":"36.89445100","Longitude":"104.16564900","pk":10895,"image_id":"2006AU8783"},{"Name":"Snuff bottle","Location":"In Storage","Latitude":"36.89445100","Longitude":"104.16564900","pk":10902,"image_id":"2006AU9234"}]
02-23 22:48:09.332 4239-4254/com.tamrefrank.www.listviewandroidstudio I/log_tag﹕ [{"Name":"Cabinet","Location":"In Storage","Latitude":"40.83990100","Longitude":"14.25185000","pk":19587,"image_id":"2006AJ6728"},{"Name":"Panel","Location":"Medieval and Renaissance, room 8, case WS EXP","Latitude":"48.87287900","Longitude":"4.63710000","pk":11371,"image_id":"2006AP3163"},{"Name":"Wallpaper","Location":"British Galleries, room 122f, case 1","Latitude":"53.47962200","Longitude":"-2.24881000","pk":19492,"image_id":"2006AU6265"},{"Name":"Portrait miniature","Location":"British Galleries, room 58c, case 2","Latitude":"52.88328900","Longitude":"-1.97685000","pk":9491,"image_id":"2006AH0271"},{"Name":"Caricature","Location":"In Storage","Latitude":"53.02513900","Longitude":"-2.18676000","pk":29979,"image_id":"2006AE9142"},{"Name":"Card game","Location":"In Storage","Latitude":"52.88328900","Longitude":"-1.97685000","pk":26483,"image_id":"2006AU5916"},{"Name":"Tile","Location":"Islamic Middle East, room 42, case WW9","Latitude":"39.76586200","Longitude":"64.42234000","pk":30220,"image_id":"2006AY5617"},{"Name":"Sculpture","Location":"Sculpture, room 22, case 2","Latitude":"52.88328900","Longitude":"-1.97685000","pk":36026,"image_id":"2006AM7780"},{"Name":"Oil painting","Location":"Prints & Drawings Study Room, room 315, case 24, shelf R","Latitude":"52.88328900","Longitude":"-1.97685000","pk":6905,"image_id":"2006AU6480"},{"Name":"Snuff bottle","Location":"In Storage","Latitude":"36.89445100","Longitude":"104.16564900","pk":10895,"image_id":"2006AU8783"},{"Name":"Snuff bottle","Location":"In Storage","Latitude":"36.89445100","Longitude":"104.16564900","pk":10902,"image_id":"2006AU9234"}]
02-23 22:48:32.712 4239-4239/com.tamrefrank.www.listviewandroidstudio I/Process﹕ Sending signal. PID: 4239 SIG: 9
Code:
package com.tamrefrank.www.listviewandroidstudio;
//All the imports happen when you auto complete. Often you may have erros when you copy paste things directly because libraries may not get imported
import android.os.AsyncTask;
import android.os.StrictMode;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends ActionBarActivity {
private String [] drinks;
JSONArray jsonObject;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set the content view to activity_main.xml
setContentView(R.layout.activity_main);
JSONArray object = new JSONArray();
object = getData();
Log.i("log_tag", jsonObject.toString());
// System.out.print("success: " + object.toString());
drinks = new String[3];
drinks[0] = "hi";
drinks[1] = "5";
drinks[2] = "3";
/**
* Lists require adapters-Adapters are the place that we store the various data items we want
to appear in the Lists. This will be handled in an adapter.
*/
ArrayAdapter<String> adapter;
//We will create the array adapter and reference it to our individual List item from the ListView and then to the array we just created- Drinks.
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,drinks);
//We finally will connect the adapter to the List View
ListView drinkLists = (ListView) findViewById(R.id.listView);
//Set the drinks array to the adapter below
drinkLists.setAdapter(adapter);
}
public JSONArray getData(){
new Thread(new Runnable() {
public void run() {
HttpGet httpGet = new HttpGet("https://stampwatch.herokuapp.com/");
HttpClient client = new DefaultHttpClient();
HttpResponse response;
StringBuilder stringBuilder = new StringBuilder();
try {
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
System.out.println(e);
}
try {
jsonObject = new JSONArray(stringBuilder.toString());
Log.i("log_tag", jsonObject.toString());
;
} catch (JSONException e) {
e.printStackTrace();
}
Log.i("log_tag", jsonObject.toString());
}
}).start();
return jsonObject;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Here:
Log.i("log_tag", jsonObject.toString());
NPE because jsonObject is null and trying to call toString() method for JSONObject using null object.
But why is the object null if I have made a request with that object?
Because jsonObject object is initialized inside getData(); method in which a Thread is used for getting data from api. means :
Log.i("log_tag", jsonObject.toString());
line executing just after starting Thread instead of wait until thread is finish.

Android communication between activity and service

I'm trying to implement a system service on Android with inter-process communication based on binding a messenger. For this I'm following this tutorial:
http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html
But no matter what I'm trying, i can't get it to work.
I found different tutorials online but in the end they are all based on the same procedure.
The app will crash right away when I'm trying to communicate with the service.
Error message
10-09 15:40:33.490 3468-3468/com.example.stenosis.testservice E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.stenosis.testservice, PID: 3468
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.stenosis.testservice/com.example.stenosis.testservice.MyActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.stenosis.testservice.MyActivity.sendMsg(MyActivity.java:87)
at com.example.stenosis.testservice.MyActivity.onCreate(MyActivity.java:49)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
MyActivity.java:
public class MyActivity extends Activity {
private ServiceConnection sConn;
private Messenger messenger;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// Service Connection to handle system callbacks
sConn = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
messenger = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// We are conntected to the service
messenger = new Messenger(service);
}
};
// We bind to the service
bindService(new Intent(this, MyService.class), sConn, Context.BIND_AUTO_CREATE);
// Try to send a message to the service
sendMsg();
}
// This class handles the Service response
class ResponseHandler extends Handler {
#Override
public void handleMessage(Message msg) {
int respCode = msg.what;
String result = "";
switch (respCode) {
case MyService.TO_UPPER_CASE_RESPONSE: {
result = msg.getData().getString("respData");
System.out.println("result");
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
}
}
}
public void sendMsg() {
String val = "This is a test";
Message msg = Message
.obtain(null, MyService.TO_UPPER_CASE);
msg.replyTo = new Messenger(new ResponseHandler());
// We pass the value
Bundle b = new Bundle();
b.putString("data", val);
msg.setData(b);
try {
messenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
MyService.java
public class MyService extends Service {
public static final int TO_UPPER_CASE = 0;
public static final int TO_UPPER_CASE_RESPONSE = 1;
private Messenger msg = new Messenger(new ConvertHanlder());;
#Override
public IBinder onBind(Intent intent) {
return msg.getBinder();
}
class ConvertHanlder extends Handler {
#Override
public void handleMessage(Message msg) {
// This is the action
int msgType = msg.what;
switch (msgType) {
case TO_UPPER_CASE: {
try {
// Incoming data
String data = msg.getData().getString("data");
Message resp = Message.obtain(null, TO_UPPER_CASE_RESPONSE);
Bundle bResp = new Bundle();
bResp.putString("respData", data.toUpperCase());
resp.setData(bResp);
msg.replyTo.send(resp);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
default:
super.handleMessage(msg);
}
}
}
}
AndroidManifest.xml
<service android:name=".MyService" android:process=":convertprc"/>
Your problem is that the messanger property is null. You are experiencing concurrency problem. The bindService method is asynchronous - it returns immediately and performs the binding in a background thread. When the binding is done, the onServiceConnected method is invoked. When you try to send the message, the messanger is still not initialized because the onServiceConnected method is hasn't been executed yet.

Categories